import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;


public class MulticastTester implements Runnable {

	
	// For thread synchronization
	ResultsTable sharedTable = new ResultsTable();
	private int numTests;
	static CyclicBarrier barrier;
	public static final String MULTICAST_KEY = "multicast";
	
	ConnectionStatus multicastStatus = new ConnectionStatus();
	
	public MulticastTester(ResultsTable r, CyclicBarrier b, int n) {
		sharedTable = r;
		barrier = b;
		numTests = n;
	}

	@Override
	public void run() {
		multicastStatus = runTests(numTests);
		sharedTable.addResult(MULTICAST_KEY, multicastStatus);
		try {
			barrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
		
	}
	
	private boolean isConnected(){
		
		try {
			
			String group = "233.3.18.5";
			int port = 30185;
	
			MulticastSocket socket = new MulticastSocket(port);
			socket.joinGroup(InetAddress.getByName(group));
			socket.setTimeToLive( 128 );
			
			byte[] buf = new byte[10*512];
			DatagramPacket packet = new DatagramPacket(buf, buf.length);
			socket.setSoTimeout(5000);

			try {
				socket.receive(packet);
				@SuppressWarnings("unused")
				String received = new String(buf, 0, packet.getLength());
				socket.leaveGroup(InetAddress.getByName(group));
				socket.close();
				return true; // test passed 
			} catch (SocketTimeoutException e) {
				return false; // test failed
			}
		} catch (IOException e) {
			return false;
		}
			
	}
	
	public ConnectionStatus runTests(int n) {
		for (int i = 0; i < n; i++){
			if (isConnected()){
				this.multicastStatus.addPassedAttempt();
			} else {
				this.multicastStatus.addFailedAttempt();
			}
		}
		return this.multicastStatus;
	}
	
	
	
	
}
